home *** CD-ROM | disk | FTP | other *** search
- /*
- * linux/atari/config.c
- *
- * Copyright (C) 1994 Björn Brauel
- *
- * 5/2/94 Roman Hodek:
- * Added setting of time_adj to get a better clock.
- *
- * 5/14/94 Roman Hodek:
- * gettod() for TT
- *
- * 5/15/94 Roman Hodek:
- * hard_reset_now() for Atari (and others?)
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file README.legal in the main directory of this archive
- * for more details.
- */
-
- /*
- * Miscellaneous atari stuff
- */
-
- #include <linux/config.h>
- #include <linux/types.h>
- #include <linux/interrupt.h>
- #include <linux/mktime.h>
- #include <linux/mm.h>
- #include <linux/bootinfo.h>
- #include <linux/mc146818rtc.h>
-
- #include <linux/atarihw.h>
- #include <linux/atariints.h>
-
- #include <asm/system.h>
-
-
- extern long time_adj; /* from kernel/sched.c */
-
-
- void atari_sched_init (isrfunc timer_routine)
- {
- /* set Timer A data Register */
- mfp.tim_dt_a=INT_TICKS;
-
- /* install interrupt service routine for MFP Timer A */
- add_isr (IRQ_MFP_TIMA, timer_routine, 0, NULL);
- /* start timer A, div = 1:100 */
- mfp.tim_ct_a = 0x06;
- /* enable timer A Interrupt */
- mfp.int_en_a |= 0x20;
-
- /* The excact frequency of our timer is 2.4576 MHz / 100 / 246 =
- * 99.90243902 Hz. This gives a difference of 9.76954 us to real time
- * per clock tick. time_adj is in us scaled by 2^24, thus it should
- * be 9.76954 * 2^24 = 163905683
- */
- time_adj = 163905683;
- }
-
-
- unsigned long atari_gettimeoffset (void)
- {
- unsigned long ticks, flags;
-
- save_flags(flags);
- cli();
-
- ticks = (unsigned long)mfp.tim_dt_a;
- restore_flags(flags);
-
- ticks = (INT_TICKS-1) - ticks;
- ticks = ticks * 10000L / INT_TICKS;
-
- return ticks;
-
- }
-
-
- #define RTC_READ(reg) \
- ({ unsigned char __val; \
- tt_rtc.regsel = (reg); \
- __val = tt_rtc.data; \
- __val; \
- })
-
- #define RTC_WRITE(reg,val) \
- do { \
- tt_rtc.regsel = (reg); \
- tt_rtc.data = (val); \
- } while(0)
-
-
- void atari_gettod( struct mktime *time )
-
- {
- int i;
- unsigned char ctrl;
-
- for (i = 0 ; i < 1000000 ; i++) /* may take up to 1 second... */
- if (RTC_READ(RTC_FREQ_SELECT) & RTC_UIP)
- break;
- for (i = 0 ; i < 1000000 ; i++) /* must try at least 2.228 ms*/
- if (!(RTC_READ(RTC_FREQ_SELECT) & RTC_UIP))
- break;
-
- time->sec = RTC_READ(RTC_SECONDS);
- time->min = RTC_READ(RTC_MINUTES);
- time->hour = RTC_READ(RTC_HOURS);
- time->day = RTC_READ(RTC_DAY_OF_MONTH);
- time->mon = RTC_READ(RTC_MONTH);
- time->year = RTC_READ(RTC_YEAR);
-
- /* Adjust values (let the setup valid for TOS) */
- time->mon--;
- time->year += 70;
-
- ctrl = RTC_READ(RTC_CONTROL);
-
- if (!(ctrl & RTC_DM_BINARY)) {
- BCD_TO_BIN(time->sec);
- BCD_TO_BIN(time->min);
- BCD_TO_BIN(time->hour);
- BCD_TO_BIN(time->day);
- BCD_TO_BIN(time->mon);
- BCD_TO_BIN(time->year);
- }
- if (!(ctrl & RTC_24H)) {
- if (time->hour & 0x80) {
- time->hour &= ~0x80;
- time->hour += 12;
- }
- }
- }
-
-
- void waitbut (void)
- {
- }
-
- void ata_serial_print (const char *str)
- {
- }
-
-
- /* ++roman:
- *
- * This function does a reset on machines that lack the ability to
- * assert the processor's _RESET signal somehow via hardware. It is
- * based on the fact that you can find the initial SP and PC values
- * after a reset at physical addresses 0 and 4. This works pretty well
- * for Atari machines, since the lowest 8 bytes of physical memory are
- * really ROM (mapped by hardware). For other 680x0 machines: don't
- * know if it works...
- *
- * To get the values at addresses 0 and 4, the MMU better is turned
- * off first. After that, we have to jump into physical address space
- * (the PC before the pmove statement points to the virtual address of
- * the code). Getting that physical address is not hard, but the code
- * becomes a bit complex since I've tried to ensure that the jump
- * statement after the pmove is in the cache already (otherwise the
- * processor can't fetch it!). For that, the code first jumps to the
- * jump statement with the (virtual) address of the pmove section in
- * an address register . The jump statement is surely in the cache
- * now. After that, that physical address of the reset code is loaded
- * into the same address register, pmove is done and the same jump
- * statements goes to the reset code. Since there are not many
- * statements between the two jumps, I hope it stays in the cache.
- *
- * The C code makes heavy use of the GCC features that you can get the
- * address of a C label. No hope to compile this with another compiler
- * than GCC!
- */
-
- void __volatile__ atari_reset( void )
-
- { long tc_val = 0, *tc_val_p = &tc_val;
- void *jmp_addr;
- void *after_jmp_addr = (void *)VTOP( &&after_jmp );
-
- cli();
- jmp_addr = &&disable_mmu;
- goto before_jmp;
-
- disable_mmu:
- jmp_addr = after_jmp_addr;
- __asm__ __volatile__
- ( "pmove %0@,tc"
- : /* no outputs */
- : "a" (tc_val_p)
- );
- before_jmp:
- __asm__ __volatile__
- ( "jmp %1@"
- : /* no outputs */
- : "a" (tc_val_p), "a" (jmp_addr)
- );
- after_jmp:
- __asm__ __volatile__
- ( "movel 0x0,sp\n\t"
- "movel 0x4,a0\n\t"
- "jmp a0@"
- : /* no outputs */
- : /* no inputs */
- : "a0"
- );
- }
-
-